package net.sf.rose.web.interceptor;

import javax.servlet.http.HttpServletRequest;

import net.sf.rose.exception.SystemException;
import net.sf.rose.jdbc.UserBean;
import net.sf.rose.jdbc.service.DataBaseFactory;
import net.sf.rose.jdbc.service.Service;
import net.sf.rose.web.OnlineUserListener;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class ControllerInterceptor {

	private static String SESSION_SERVICE = "SESSION_SERVICE";

	private Logger logger = Logger.getLogger(ControllerInterceptor.class);

	/**
	 * 功能：借助Spring的AOP方法，截获所有Action类
	 * 如果需要，注入数据库连接服务类，并全面负责数据连接管理
	 */
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
		logger.info("excute class: " + pjp.getTarget().getClass().getName() + "'s method:" + pjp.getSignature().getName());
		long time = System.currentTimeMillis();
		Object[] arg = pjp.getArgs();
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		Service service = null;
		for (Object obj : arg) {
			if (obj != null && obj instanceof Service) {
				service = (Service) obj;
				service.setConnectFactory(DataBaseFactory.getFactory());
				UserBean user = OnlineUserListener.getOnlineUser(request);
				if (user != null) {
					service.setUser(user);
				}
				request.setAttribute(SESSION_SERVICE, service);
			}
		}
		Object retVal = pjp.proceed(arg);
		if (service != null) {
			service.close();
		}
		time = System.currentTimeMillis() - time;
		logger.info("process time: " + time + " ms");
		return retVal;
	}

	/**
	 * 功能：1.抛出异常时关闭数据库连接
	 * 2.捕获所有的异常，记录日志，并处理后返回信息给前台用户
	 * @throws Throwable 
	 */
	public void doThrowing(JoinPoint jp, Throwable ex) throws Throwable {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		Object obj = request.getAttribute(SESSION_SERVICE);
		if (obj != null) {
			Service service = (Service) obj;
			service.close();
		}
		if (!(ex instanceof SystemException)) {
			logger.warn("发生未捕获的异常！", ex);
		}
		logger.warn("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception");
		if (ex instanceof SystemException) {
			request.setAttribute("exception", ex);
		} else {
			Throwable te = ex.getCause();
			if (te != null) {
				request.setAttribute("exception", te);
			} else {
				request.setAttribute("exception", ex);
			}
		}
		throw ex;
	}

}
